﻿package org.flixel
{
    import flash.display.*;
    import flash.geom.*;
    import org.flixel.system.*;

    public class FlxTilemap extends FlxObject
    {
        public var auto:uint;
        public var widthInTiles:uint;
        public var heightInTiles:uint;
        public var totalTiles:uint;
        protected var _flashPoint:Point;
        protected var _flashRect:Rectangle;
        protected var _tiles:BitmapData;
        protected var _buffers:Array;
        protected var _data:Array;
        protected var _rects:Array;
        protected var _tileWidth:uint;
        protected var _tileHeight:uint;
        protected var _tileObjects:Array;
        protected var _debugTileNotSolid:BitmapData;
        protected var _debugTilePartial:BitmapData;
        protected var _debugTileSolid:BitmapData;
        protected var _debugRect:Rectangle;
        protected var _lastVisualDebug:Boolean;
        protected var _startingIndex:uint;
        public static var ImgAuto:Class = FlxTilemap_ImgAuto;
        public static var ImgAutoAlt:Class = FlxTilemap_ImgAutoAlt;
        public static const OFF:uint = 0;
        public static const AUTO:uint = 1;
        public static const ALT:uint = 2;

        public function FlxTilemap()
        {
            this.auto = OFF;
            this.widthInTiles = 0;
            this.heightInTiles = 0;
            this.totalTiles = 0;
            this._buffers = new Array();
            this._flashPoint = new Point();
            this._flashRect = null;
            this._data = null;
            this._tileWidth = 0;
            this._tileHeight = 0;
            this._rects = null;
            this._tiles = null;
            this._tileObjects = null;
            immovable = true;
            cameras = null;
            this._debugTileNotSolid = null;
            this._debugTilePartial = null;
            this._debugTileSolid = null;
            this._debugRect = null;
            this._lastVisualDebug = FlxG.visualDebug;
            this._startingIndex = 0;
            return;
        }// end function

        override public function destroy() : void
        {
            this._flashPoint = null;
            this._flashRect = null;
            this._tiles = null;
            var _loc_1:uint = 0;
            var _loc_2:* = this._tileObjects.length;
            while (_loc_1 < _loc_2)
            {
                
                (this._tileObjects[_loc_1++] as FlxTile).destroy();
            }
            this._tileObjects = null;
            _loc_1 = 0;
            _loc_2 = this._buffers.length;
            while (_loc_1 < _loc_2)
            {
                
                (this._buffers[_loc_1++] as FlxTilemapBuffer).destroy();
            }
            this._buffers = null;
            this._data = null;
            this._rects = null;
            this._debugTileNotSolid = null;
            this._debugTilePartial = null;
            this._debugTileSolid = null;
            this._debugRect = null;
            super.destroy();
            return;
        }// end function

        public function loadMap(param1:String, param2:Class, param3:uint = 0, param4:uint = 0, param5:uint = 0, param6:uint = 0, param7:uint = 1, param8:uint = 1) : FlxTilemap
        {
            var _loc_9:Array = null;
            var _loc_12:uint = 0;
            var _loc_13:uint = 0;
            var _loc_15:uint = 0;
            this.auto = param5;
            this._startingIndex = param6;
            var _loc_10:* = param1.split("\n");
            this.heightInTiles = _loc_10.length;
            this._data = new Array();
            var _loc_11:uint = 0;
            while (_loc_11 < this.heightInTiles)
            {
                
                _loc_9 = _loc_10[_loc_11++].split(",");
                if (_loc_9.length <= 1)
                {
                    (this.heightInTiles - 1);
                    continue;
                }
                if (this.widthInTiles == 0)
                {
                    this.widthInTiles = _loc_9.length;
                }
                _loc_12 = 0;
                while (_loc_12 < this.widthInTiles)
                {
                    
                    this._data.push(uint(_loc_9[_loc_12++]));
                }
            }
            this.totalTiles = this.widthInTiles * this.heightInTiles;
            if (this.auto > OFF)
            {
                this._startingIndex = 1;
                param7 = 1;
                param8 = 1;
                _loc_13 = 0;
                while (_loc_13 < this.totalTiles)
                {
                    
                    this.autoTile(_loc_13++);
                }
            }
            this._tiles = FlxG.addBitmap(param2);
            this._tileWidth = param3;
            if (this._tileWidth == 0)
            {
                this._tileWidth = this._tiles.height;
            }
            this._tileHeight = param4;
            if (this._tileHeight == 0)
            {
                this._tileHeight = this._tileWidth;
            }
            _loc_13 = 0;
            var _loc_14:* = this._tiles.width / this._tileWidth * (this._tiles.height / this._tileHeight);
            if (this.auto > OFF)
            {
                _loc_14 = _loc_14 + 1;
            }
            this._tileObjects = new Array(_loc_14);
            while (_loc_13 < _loc_14)
            {
                
                this._tileObjects[_loc_13] = new FlxTile(this, _loc_13, this._tileWidth, this._tileHeight, _loc_13 >= param7, _loc_13 >= param8 ? (allowCollisions) : (NONE));
                _loc_13 = _loc_13 + 1;
            }
            this._debugTileNotSolid = this.makeDebugTile(FlxG.BLUE);
            this._debugTilePartial = this.makeDebugTile(FlxG.PINK);
            this._debugTileSolid = this.makeDebugTile(FlxG.GREEN);
            this._debugRect = new Rectangle(0, 0, this._tileWidth, this._tileHeight);
            width = this.widthInTiles * this._tileWidth;
            height = this.heightInTiles * this._tileHeight;
            this._rects = new Array(this.totalTiles);
            _loc_13 = 0;
            while (_loc_13 < this.totalTiles)
            {
                
                this.updateTile(_loc_13++);
            }
            return this;
        }// end function

        protected function makeDebugTile(param1:uint) : BitmapData
        {
            var _loc_2:BitmapData = null;
            _loc_2 = new BitmapData(this._tileWidth, this._tileHeight, true, 0);
            var _loc_3:* = FlxG.flashGfx;
            _loc_3.clear();
            _loc_3.moveTo(0, 0);
            _loc_3.lineStyle(1, param1, 0.5);
            _loc_3.lineTo((this._tileWidth - 1), 0);
            _loc_3.lineTo((this._tileWidth - 1), (this._tileHeight - 1));
            _loc_3.lineTo(0, (this._tileHeight - 1));
            _loc_3.lineTo(0, 0);
            _loc_2.draw(FlxG.flashGfxSprite);
            return _loc_2;
        }// end function

        override public function update() : void
        {
            if (this._lastVisualDebug != FlxG.visualDebug)
            {
                this._lastVisualDebug = FlxG.visualDebug;
                this.setDirty();
            }
            return;
        }// end function

        protected function drawTilemap(param1:FlxTilemapBuffer, param2:FlxCamera) : void
        {
            var _loc_9:uint = 0;
            var _loc_10:uint = 0;
            var _loc_11:FlxTile = null;
            var _loc_12:BitmapData = null;
            param1.fill();
            _point.x = int(param2.scroll.x * scrollFactor.x) - x;
            _point.y = int(param2.scroll.y * scrollFactor.y) - y;
            var _loc_3:* = (_point.x + (_point.x > 0 ? (1e-007) : (-1e-007))) / this._tileWidth;
            var _loc_4:* = (_point.y + (_point.y > 0 ? (1e-007) : (-1e-007))) / this._tileHeight;
            var _loc_5:* = param1.rows;
            var _loc_6:* = param1.columns;
            if (_loc_3 < 0)
            {
                _loc_3 = 0;
            }
            if (_loc_3 > this.widthInTiles - _loc_6)
            {
                _loc_3 = this.widthInTiles - _loc_6;
            }
            if (_loc_4 < 0)
            {
                _loc_4 = 0;
            }
            if (_loc_4 > this.heightInTiles - _loc_5)
            {
                _loc_4 = this.heightInTiles - _loc_5;
            }
            var _loc_7:* = _loc_4 * this.widthInTiles + _loc_3;
            this._flashPoint.y = 0;
            var _loc_8:uint = 0;
            while (_loc_8 < _loc_5)
            {
                
                _loc_10 = _loc_7;
                _loc_9 = 0;
                this._flashPoint.x = 0;
                while (_loc_9 < _loc_6)
                {
                    
                    this._flashRect = this._rects[_loc_10] as Rectangle;
                    if (this._flashRect != null)
                    {
                        param1.pixels.copyPixels(this._tiles, this._flashRect, this._flashPoint, null, null, true);
                        if (FlxG.visualDebug && !ignoreDrawDebug)
                        {
                            _loc_11 = this._tileObjects[this._data[_loc_10]];
                            if (_loc_11 != null)
                            {
                                if (_loc_11.allowCollisions <= NONE)
                                {
                                    _loc_12 = this._debugTileNotSolid;
                                }
                                else if (_loc_11.allowCollisions != ANY)
                                {
                                    _loc_12 = this._debugTilePartial;
                                }
                                else
                                {
                                    _loc_12 = this._debugTileSolid;
                                }
                                param1.pixels.copyPixels(_loc_12, this._debugRect, this._flashPoint, null, null, true);
                            }
                        }
                    }
                    this._flashPoint.x = this._flashPoint.x + this._tileWidth;
                    _loc_9 = _loc_9 + 1;
                    _loc_10 = _loc_10 + 1;
                }
                _loc_7 = _loc_7 + this.widthInTiles;
                this._flashPoint.y = this._flashPoint.y + this._tileHeight;
                _loc_8 = _loc_8 + 1;
            }
            param1.x = _loc_3 * this._tileWidth;
            param1.y = _loc_4 * this._tileHeight;
            return;
        }// end function

        override public function draw() : void
        {
            var _loc_1:FlxCamera = null;
            var _loc_2:FlxTilemapBuffer = null;
            if (_flickerTimer != 0)
            {
                _flicker = !_flicker;
                if (_flicker)
                {
                    return;
                }
            }
            if (cameras == null)
            {
                cameras = FlxG.cameras;
            }
            var _loc_3:uint = 0;
            var _loc_4:* = cameras.length;
            while (_loc_3 < _loc_4)
            {
                
                _loc_1 = cameras[_loc_3];
                if (this._buffers[_loc_3] == null)
                {
                    this._buffers[_loc_3] = new FlxTilemapBuffer(this._tileWidth, this._tileHeight, this.widthInTiles, this.heightInTiles, _loc_1);
                }
                _loc_2 = this._buffers[_loc_3++] as FlxTilemapBuffer;
                if (!_loc_2.dirty)
                {
                    _point.x = x - int(_loc_1.scroll.x * scrollFactor.x) + _loc_2.x;
                    _point.y = y - int(_loc_1.scroll.y * scrollFactor.y) + _loc_2.y;
                    _loc_2.dirty = _point.x > 0 || _point.y > 0 || _point.x + _loc_2.width < _loc_1.width || _point.y + _loc_2.height < _loc_1.height;
                }
                if (_loc_2.dirty)
                {
                    this.drawTilemap(_loc_2, _loc_1);
                    _loc_2.dirty = false;
                }
                this._flashPoint.x = x - int(_loc_1.scroll.x * scrollFactor.x) + _loc_2.x;
                this._flashPoint.y = y - int(_loc_1.scroll.y * scrollFactor.y) + _loc_2.y;
                this._flashPoint.x = this._flashPoint.x + (this._flashPoint.x > 0 ? (1e-007) : (-1e-007));
                this._flashPoint.y = this._flashPoint.y + (this._flashPoint.y > 0 ? (1e-007) : (-1e-007));
                _loc_2.draw(_loc_1, this._flashPoint);
                var _loc_6:* = _VISIBLECOUNT + 1;
                _VISIBLECOUNT = _loc_6;
            }
            return;
        }// end function

        public function getData(param1:Boolean = false) : Array
        {
            if (!param1)
            {
                return this._data;
            }
            var _loc_2:uint = 0;
            var _loc_3:* = this._data.length;
            var _loc_4:* = new Array(_loc_3);
            while (_loc_2 < _loc_3)
            {
                
                _loc_4[_loc_2] = (this._tileObjects[this._data[_loc_2]] as FlxTile).allowCollisions > 0 ? (1) : (0);
                _loc_2 = _loc_2 + 1;
            }
            return _loc_4;
        }// end function

        public function setDirty(param1:Boolean = true) : void
        {
            var _loc_2:uint = 0;
            var _loc_3:* = this._buffers.length;
            while (_loc_2 < _loc_3)
            {
                
                (this._buffers[_loc_2++] as FlxTilemapBuffer).dirty = param1;
            }
            return;
        }// end function

        public function findPath(param1:FlxPoint, param2:FlxPoint, param3:Boolean = true, param4:Boolean = false) : FlxPath
        {
            var _loc_9:FlxPoint = null;
            var _loc_5:* = int((param1.y - y) / this._tileHeight) * this.widthInTiles + int((param1.x - x) / this._tileWidth);
            var _loc_6:* = int((param2.y - y) / this._tileHeight) * this.widthInTiles + int((param2.x - x) / this._tileWidth);
            if ((this._tileObjects[this._data[_loc_5]] as FlxTile).allowCollisions > 0 || (this._tileObjects[this._data[_loc_6]] as FlxTile).allowCollisions > 0)
            {
                return null;
            }
            var _loc_7:* = this.computePathDistance(_loc_5, _loc_6);
            if (this.computePathDistance(_loc_5, _loc_6) == null)
            {
                return null;
            }
            var _loc_8:* = new Array();
            this.walkPath(_loc_7, _loc_6, _loc_8);
            _loc_9 = _loc_8[(_loc_8.length - 1)] as FlxPoint;
            _loc_9.x = param1.x;
            _loc_9.y = param1.y;
            _loc_9 = _loc_8[0] as FlxPoint;
            _loc_9.x = param2.x;
            _loc_9.y = param2.y;
            if (param3)
            {
                this.simplifyPath(_loc_8);
            }
            if (param4)
            {
                this.raySimplifyPath(_loc_8);
            }
            var _loc_10:* = new FlxPath();
            var _loc_11:* = _loc_8.length - 1;
            while (_loc_11 >= 0)
            {
                
                _loc_9 = _loc_8[_loc_11--] as FlxPoint;
                if (_loc_9 != null)
                {
                    _loc_10.addPoint(_loc_9, true);
                }
            }
            return _loc_10;
        }// end function

        protected function simplifyPath(param1:Array) : void
        {
            var _loc_2:Number = NaN;
            var _loc_3:Number = NaN;
            var _loc_5:FlxPoint = null;
            var _loc_4:* = param1[0];
            var _loc_6:uint = 1;
            var _loc_7:* = param1.length - 1;
            while (_loc_6 < _loc_7)
            {
                
                _loc_5 = param1[_loc_6];
                _loc_2 = (_loc_5.x - _loc_4.x) / (_loc_5.y - _loc_4.y);
                _loc_3 = (_loc_5.x - param1[(_loc_6 + 1)].x) / (_loc_5.y - param1[(_loc_6 + 1)].y);
                if (_loc_4.x == param1[(_loc_6 + 1)].x || _loc_4.y == param1[(_loc_6 + 1)].y || _loc_2 == _loc_3)
                {
                    param1[_loc_6] = null;
                }
                else
                {
                    _loc_4 = _loc_5;
                }
                _loc_6 = _loc_6 + 1;
            }
            return;
        }// end function

        protected function raySimplifyPath(param1:Array) : void
        {
            var _loc_4:FlxPoint = null;
            var _loc_2:* = param1[0];
            var _loc_3:int = -1;
            var _loc_5:uint = 1;
            var _loc_6:* = param1.length;
            while (_loc_5 < _loc_6)
            {
                
                _loc_4 = param1[_loc_5++];
                if (_loc_4 != null)
                {
                    if (this.ray(_loc_2, _loc_4, _point))
                    {
                        if (_loc_3 >= 0)
                        {
                            param1[_loc_3] = null;
                        }
                    }
                    else
                    {
                        _loc_2 = param1[_loc_3];
                    }
                    _loc_3 = _loc_5 - 1;
                }
            }
            return;
        }// end function

        protected function computePathDistance(param1:uint, param2:uint) : Array
        {
            var _loc_8:Array = null;
            var _loc_9:uint = 0;
            var _loc_10:Boolean = false;
            var _loc_11:Boolean = false;
            var _loc_12:Boolean = false;
            var _loc_13:Boolean = false;
            var _loc_14:uint = 0;
            var _loc_16:uint = 0;
            var _loc_3:* = this.widthInTiles * this.heightInTiles;
            var _loc_4:* = new Array(_loc_3);
            var _loc_5:int = 0;
            while (_loc_5 < _loc_3)
            {
                
                if ((this._tileObjects[this._data[_loc_5]] as FlxTile).allowCollisions)
                {
                    _loc_4[_loc_5] = -2;
                }
                else
                {
                    _loc_4[_loc_5] = -1;
                }
                _loc_5++;
            }
            _loc_4[param1] = 0;
            var _loc_6:uint = 1;
            var _loc_7:Array = [param1];
            var _loc_15:Boolean = false;
            while (_loc_7.length > 0)
            {
                
                _loc_8 = _loc_7;
                _loc_7 = new Array();
                _loc_5 = 0;
                _loc_14 = _loc_8.length;
                while (_loc_5 < _loc_14)
                {
                    
                    _loc_9 = _loc_8[_loc_5++];
                    if (_loc_9 == param2)
                    {
                        _loc_15 = true;
                        _loc_7.length = 0;
                        break;
                    }
                    _loc_10 = _loc_9 % this.widthInTiles > 0;
                    _loc_11 = _loc_9 % this.widthInTiles < (this.widthInTiles - 1);
                    _loc_12 = _loc_9 / this.widthInTiles > 0;
                    _loc_13 = _loc_9 / this.widthInTiles < (this.heightInTiles - 1);
                    if (_loc_12)
                    {
                        _loc_16 = _loc_9 - this.widthInTiles;
                        if (_loc_4[_loc_16] == -1)
                        {
                            _loc_4[_loc_16] = _loc_6;
                            _loc_7.push(_loc_16);
                        }
                    }
                    if (_loc_11)
                    {
                        _loc_16 = _loc_9 + 1;
                        if (_loc_4[_loc_16] == -1)
                        {
                            _loc_4[_loc_16] = _loc_6;
                            _loc_7.push(_loc_16);
                        }
                    }
                    if (_loc_13)
                    {
                        _loc_16 = _loc_9 + this.widthInTiles;
                        if (_loc_4[_loc_16] == -1)
                        {
                            _loc_4[_loc_16] = _loc_6;
                            _loc_7.push(_loc_16);
                        }
                    }
                    if (_loc_10)
                    {
                        _loc_16 = _loc_9 - 1;
                        if (_loc_4[_loc_16] == -1)
                        {
                            _loc_4[_loc_16] = _loc_6;
                            _loc_7.push(_loc_16);
                        }
                    }
                    if (_loc_12 && _loc_11)
                    {
                        _loc_16 = _loc_9 - this.widthInTiles + 1;
                        if (_loc_4[_loc_16] == -1 && _loc_4[_loc_9 - this.widthInTiles] >= -1 && _loc_4[(_loc_9 + 1)] >= -1)
                        {
                            _loc_4[_loc_16] = _loc_6;
                            _loc_7.push(_loc_16);
                        }
                    }
                    if (_loc_11 && _loc_13)
                    {
                        _loc_16 = _loc_9 + this.widthInTiles + 1;
                        if (_loc_4[_loc_16] == -1 && _loc_4[_loc_9 + this.widthInTiles] >= -1 && _loc_4[(_loc_9 + 1)] >= -1)
                        {
                            _loc_4[_loc_16] = _loc_6;
                            _loc_7.push(_loc_16);
                        }
                    }
                    if (_loc_10 && _loc_13)
                    {
                        _loc_16 = _loc_9 + this.widthInTiles - 1;
                        if (_loc_4[_loc_16] == -1 && _loc_4[_loc_9 + this.widthInTiles] >= -1 && _loc_4[(_loc_9 - 1)] >= -1)
                        {
                            _loc_4[_loc_16] = _loc_6;
                            _loc_7.push(_loc_16);
                        }
                    }
                    if (_loc_12 && _loc_10)
                    {
                        _loc_16 = _loc_9 - this.widthInTiles - 1;
                        if (_loc_4[_loc_16] == -1 && _loc_4[_loc_9 - this.widthInTiles] >= -1 && _loc_4[(_loc_9 - 1)] >= -1)
                        {
                            _loc_4[_loc_16] = _loc_6;
                            _loc_7.push(_loc_16);
                        }
                    }
                }
                _loc_6 = _loc_6 + 1;
            }
            if (!_loc_15)
            {
                _loc_4 = null;
            }
            return _loc_4;
        }// end function

        protected function walkPath(param1:Array, param2:uint, param3:Array) : void
        {
            var _loc_9:uint = 0;
            param3.push(new FlxPoint(x + uint(param2 % this.widthInTiles) * this._tileWidth + this._tileWidth * 0.5, y + uint(param2 / this.widthInTiles) * this._tileHeight + this._tileHeight * 0.5));
            if (param1[param2] == 0)
            {
                return;
            }
            var _loc_4:* = param2 % this.widthInTiles > 0;
            var _loc_5:* = param2 % this.widthInTiles < (this.widthInTiles - 1);
            var _loc_6:* = param2 / this.widthInTiles > 0;
            var _loc_7:* = param2 / this.widthInTiles < (this.heightInTiles - 1);
            var _loc_8:* = param1[param2];
            if (_loc_6)
            {
                _loc_9 = param2 - this.widthInTiles;
                if (param1[_loc_9] >= 0 && param1[_loc_9] < _loc_8)
                {
                    this.walkPath(param1, _loc_9, param3);
                    return;
                }
            }
            if (_loc_5)
            {
                _loc_9 = param2 + 1;
                if (param1[_loc_9] >= 0 && param1[_loc_9] < _loc_8)
                {
                    this.walkPath(param1, _loc_9, param3);
                    return;
                }
            }
            if (_loc_7)
            {
                _loc_9 = param2 + this.widthInTiles;
                if (param1[_loc_9] >= 0 && param1[_loc_9] < _loc_8)
                {
                    this.walkPath(param1, _loc_9, param3);
                    return;
                }
            }
            if (_loc_4)
            {
                _loc_9 = param2 - 1;
                if (param1[_loc_9] >= 0 && param1[_loc_9] < _loc_8)
                {
                    this.walkPath(param1, _loc_9, param3);
                    return;
                }
            }
            if (_loc_6 && _loc_5)
            {
                _loc_9 = param2 - this.widthInTiles + 1;
                if (param1[_loc_9] >= 0 && param1[_loc_9] < _loc_8)
                {
                    this.walkPath(param1, _loc_9, param3);
                    return;
                }
            }
            if (_loc_5 && _loc_7)
            {
                _loc_9 = param2 + this.widthInTiles + 1;
                if (param1[_loc_9] >= 0 && param1[_loc_9] < _loc_8)
                {
                    this.walkPath(param1, _loc_9, param3);
                    return;
                }
            }
            if (_loc_4 && _loc_7)
            {
                _loc_9 = param2 + this.widthInTiles - 1;
                if (param1[_loc_9] >= 0 && param1[_loc_9] < _loc_8)
                {
                    this.walkPath(param1, _loc_9, param3);
                    return;
                }
            }
            if (_loc_6 && _loc_4)
            {
                _loc_9 = param2 - this.widthInTiles - 1;
                if (param1[_loc_9] >= 0 && param1[_loc_9] < _loc_8)
                {
                    this.walkPath(param1, _loc_9, param3);
                    return;
                }
            }
            return;
        }// end function

        override public function overlaps(param1:FlxBasic, param2:Boolean = false, param3:FlxCamera = null) : Boolean
        {
            var _loc_4:Boolean = false;
            var _loc_5:FlxBasic = null;
            var _loc_6:uint = 0;
            var _loc_7:Array = null;
            if (param1 is FlxGroup)
            {
                _loc_4 = false;
                _loc_6 = 0;
                _loc_7 = (param1 as FlxGroup).members;
                while (_loc_6 < length)
                {
                    
                    _loc_5 = _loc_7[_loc_6++] as FlxBasic;
                    if (_loc_5 is FlxObject)
                    {
                        if (this.overlapsWithCallback(_loc_5 as FlxObject))
                        {
                            _loc_4 = true;
                        }
                        continue;
                    }
                    if (this.overlaps(_loc_5, param2, param3))
                    {
                        _loc_4 = true;
                    }
                }
                return _loc_4;
            }
            else if (param1 is FlxObject)
            {
                return this.overlapsWithCallback(param1 as FlxObject);
            }
            return false;
        }// end function

        override public function overlapsAt(param1:Number, param2:Number, param3:FlxBasic, param4:Boolean = false, param5:FlxCamera = null) : Boolean
        {
            var _loc_6:Boolean = false;
            var _loc_7:FlxBasic = null;
            var _loc_8:uint = 0;
            var _loc_9:Array = null;
            if (param3 is FlxGroup)
            {
                _loc_6 = false;
                _loc_8 = 0;
                _loc_9 = (param3 as FlxGroup).members;
                while (_loc_8 < length)
                {
                    
                    _loc_7 = _loc_9[_loc_8++] as FlxBasic;
                    if (_loc_7 is FlxObject)
                    {
                        _point.x = param1;
                        _point.y = param2;
                        if (this.overlapsWithCallback(_loc_7 as FlxObject, null, false, _point))
                        {
                            _loc_6 = true;
                        }
                        continue;
                    }
                    if (this.overlapsAt(param1, param2, _loc_7, param4, param5))
                    {
                        _loc_6 = true;
                    }
                }
                return _loc_6;
            }
            else if (param3 is FlxObject)
            {
                _point.x = param1;
                _point.y = param2;
                return this.overlapsWithCallback(param3 as FlxObject, null, false, _point);
            }
            return false;
        }// end function

        public function overlapsWithCallback(param1:FlxObject, param2:Function = null, param3:Boolean = false, param4:FlxPoint = null) : Boolean
        {
            var _loc_14:uint = 0;
            var _loc_15:FlxTile = null;
            var _loc_16:Boolean = false;
            var _loc_5:Boolean = false;
            var _loc_6:* = x;
            var _loc_7:* = y;
            if (param4 != null)
            {
                _loc_6 = param4.x;
                _loc_7 = param4.y;
            }
            var _loc_8:* = FlxU.floor((param1.x - _loc_6) / this._tileWidth);
            var _loc_9:* = FlxU.floor((param1.y - _loc_7) / this._tileHeight);
            var _loc_10:* = _loc_8 + FlxU.ceil(param1.width / this._tileWidth) + 1;
            var _loc_11:* = _loc_9 + FlxU.ceil(param1.height / this._tileHeight) + 1;
            if (_loc_8 < 0)
            {
                _loc_8 = 0;
            }
            if (_loc_9 < 0)
            {
                _loc_9 = 0;
            }
            if (_loc_10 > this.widthInTiles)
            {
                _loc_10 = this.widthInTiles;
            }
            if (_loc_11 > this.heightInTiles)
            {
                _loc_11 = this.heightInTiles;
            }
            var _loc_12:* = _loc_9 * this.widthInTiles;
            var _loc_13:* = _loc_9;
            var _loc_17:* = _loc_6 - last.x;
            var _loc_18:* = _loc_7 - last.y;
            while (_loc_13 < _loc_11)
            {
                
                _loc_14 = _loc_8;
                while (_loc_14 < _loc_10)
                {
                    
                    _loc_16 = false;
                    _loc_15 = this._tileObjects[this._data[_loc_12 + _loc_14]] as FlxTile;
                    if (_loc_15.allowCollisions)
                    {
                        _loc_15.x = _loc_6 + _loc_14 * this._tileWidth;
                        _loc_15.y = _loc_7 + _loc_13 * this._tileHeight;
                        _loc_15.last.x = _loc_15.x - _loc_17;
                        _loc_15.last.y = _loc_15.y - _loc_18;
                        if (param2 != null)
                        {
                            if (param3)
                            {
                                _loc_16 = this.param2(param1, _loc_15);
                            }
                            else
                            {
                                _loc_16 = this.param2(_loc_15, param1);
                            }
                        }
                        else
                        {
                            _loc_16 = param1.x + param1.width > _loc_15.x && param1.x < _loc_15.x + _loc_15.width && param1.y + param1.height > _loc_15.y && param1.y < _loc_15.y + _loc_15.height;
                        }
                        if (_loc_16)
                        {
                            if (_loc_15.callback != null && (_loc_15.filter == null || param1 is _loc_15.filter))
                            {
                                _loc_15.mapIndex = _loc_12 + _loc_14;
                                _loc_15.callback(_loc_15, param1);
                            }
                            _loc_5 = true;
                        }
                    }
                    else if (_loc_15.callback != null && (_loc_15.filter == null || param1 is _loc_15.filter))
                    {
                        _loc_15.mapIndex = _loc_12 + _loc_14;
                        _loc_15.callback(_loc_15, param1);
                    }
                    _loc_14 = _loc_14 + 1;
                }
                _loc_12 = _loc_12 + this.widthInTiles;
                _loc_13 = _loc_13 + 1;
            }
            return _loc_5;
        }// end function

        override public function overlapsPoint(param1:FlxPoint, param2:Boolean = false, param3:FlxCamera = null) : Boolean
        {
            if (!param2)
            {
                return (this._tileObjects[this._data[uint(uint((param1.y - y) / this._tileHeight) * this.widthInTiles + (param1.x - x) / this._tileWidth)]] as FlxTile).allowCollisions > 0;
            }
            if (param3 == null)
            {
                param3 = FlxG.camera;
            }
            param1.x = param1.x - param3.scroll.x;
            param1.y = param1.y - param3.scroll.y;
            getScreenXY(_point, param3);
            return (this._tileObjects[this._data[uint(uint((param1.y - _point.y) / this._tileHeight) * this.widthInTiles + (param1.x - _point.x) / this._tileWidth)]] as FlxTile).allowCollisions > 0;
        }// end function

        public function getTile(param1:uint, param2:uint) : uint
        {
            return this._data[param2 * this.widthInTiles + param1] as uint;
        }// end function

        public function getTileByIndex(param1:uint) : uint
        {
            return this._data[param1] as uint;
        }// end function

        public function getTileInstances(param1:uint) : Array
        {
            var _loc_2:Array = null;
            var _loc_3:uint = 0;
            var _loc_4:* = this.widthInTiles * this.heightInTiles;
            while (_loc_3 < _loc_4)
            {
                
                if (this._data[_loc_3] == param1)
                {
                    if (_loc_2 == null)
                    {
                        _loc_2 = new Array();
                    }
                    _loc_2.push(_loc_3);
                }
                _loc_3 = _loc_3 + 1;
            }
            return _loc_2;
        }// end function

        public function getTileCoords(param1:uint, param2:Boolean = true) : Array
        {
            var _loc_4:FlxPoint = null;
            var _loc_3:Array = null;
            var _loc_5:uint = 0;
            var _loc_6:* = this.widthInTiles * this.heightInTiles;
            while (_loc_5 < _loc_6)
            {
                
                if (this._data[_loc_5] == param1)
                {
                    _loc_4 = new FlxPoint(x + uint(_loc_5 % this.widthInTiles) * this._tileWidth, y + uint(_loc_5 / this.widthInTiles) * this._tileHeight);
                    if (param2)
                    {
                        _loc_4.x = _loc_4.x + this._tileWidth * 0.5;
                        _loc_4.y = _loc_4.y + this._tileHeight * 0.5;
                    }
                    if (_loc_3 == null)
                    {
                        _loc_3 = new Array();
                    }
                    _loc_3.push(_loc_4);
                }
                _loc_5 = _loc_5 + 1;
            }
            return _loc_3;
        }// end function

        public function setTile(param1:uint, param2:uint, param3:uint, param4:Boolean = true) : Boolean
        {
            if (param1 >= this.widthInTiles || param2 >= this.heightInTiles)
            {
                return false;
            }
            return this.setTileByIndex(param2 * this.widthInTiles + param1, param3, param4);
        }// end function

        public function setTileByIndex(param1:uint, param2:uint, param3:Boolean = true) : Boolean
        {
            var _loc_5:uint = 0;
            if (param1 >= this._data.length)
            {
                return false;
            }
            var _loc_4:Boolean = true;
            this._data[param1] = param2;
            if (!param3)
            {
                return _loc_4;
            }
            this.setDirty();
            if (this.auto == OFF)
            {
                this.updateTile(param1);
                return _loc_4;
            }
            var _loc_7:* = --int(param1 / this.widthInTiles) + 3;
            var _loc_8:* = param1 % this.widthInTiles - 1;
            var _loc_9:* = param1 % this.widthInTiles - 1 + 3;
            while (_loc_6 < _loc_7)
            {
                
                _loc_8 = _loc_9 - 3;
                while (_loc_8 < _loc_9)
                {
                    
                    if (--int(param1 / this.widthInTiles) >= 0 && _loc_6 < this.heightInTiles && _loc_8 >= 0 && _loc_8 < this.widthInTiles)
                    {
                        _loc_5 = _loc_6 * this.widthInTiles + _loc_8;
                        this.autoTile(_loc_5);
                        this.updateTile(_loc_5);
                    }
                    _loc_8++;
                }
                _loc_6++;
            }
            return _loc_4;
        }// end function

        public function setTileProperties(param1:uint, param2:uint = 4369, param3:Function = null, param4:Class = null, param5:uint = 1) : void
        {
            var _loc_6:FlxTile = null;
            if (param5 <= 0)
            {
                param5 = 1;
            }
            var _loc_7:* = param1;
            var _loc_8:* = param1 + param5;
            while (_loc_7 < _loc_8)
            {
                
                _loc_6 = this._tileObjects[_loc_7++] as FlxTile;
                _loc_6.allowCollisions = param2;
                _loc_6.callback = param3;
                _loc_6.filter = param4;
            }
            return;
        }// end function

        public function follow(param1:FlxCamera = null, param2:int = 0, param3:Boolean = true) : void
        {
            if (param1 == null)
            {
                param1 = FlxG.camera;
            }
            param1.setBounds(x + param2 * this._tileWidth, y + param2 * this._tileHeight, width - param2 * this._tileWidth * 2, height - param2 * this._tileHeight * 2, param3);
            return;
        }// end function

        public function getBounds(param1:FlxRect = null) : FlxRect
        {
            if (param1 == null)
            {
                param1 = new FlxRect();
            }
            return param1.make(x, y, width, height);
        }// end function

        public function ray(param1:FlxPoint, param2:FlxPoint, param3:FlxPoint = null, param4:Number = 1) : Boolean
        {
            var _loc_14:uint = 0;
            var _loc_15:uint = 0;
            var _loc_17:Number = NaN;
            var _loc_18:Number = NaN;
            var _loc_19:Number = NaN;
            var _loc_20:Number = NaN;
            var _loc_21:Number = NaN;
            var _loc_5:* = this._tileWidth;
            if (this._tileHeight < this._tileWidth)
            {
                _loc_5 = this._tileHeight;
            }
            _loc_5 = _loc_5 / param4;
            var _loc_6:* = param2.x - param1.x;
            var _loc_7:* = param2.y - param1.y;
            var _loc_8:* = Math.sqrt(_loc_6 * _loc_6 + _loc_7 * _loc_7);
            var _loc_9:* = Math.ceil(_loc_8 / _loc_5);
            var _loc_10:* = _loc_6 / _loc_9;
            var _loc_11:* = _loc_7 / _loc_9;
            var _loc_12:* = param1.x - _loc_10 - x;
            var _loc_13:* = param1.y - _loc_11 - y;
            var _loc_16:uint = 0;
            while (_loc_16 < _loc_9)
            {
                
                _loc_12 = _loc_12 + _loc_10;
                _loc_13 = _loc_13 + _loc_11;
                if (_loc_12 < 0 || _loc_12 > width || _loc_13 < 0 || _loc_13 > height)
                {
                    _loc_16 = _loc_16 + 1;
                    continue;
                }
                _loc_14 = _loc_12 / this._tileWidth;
                _loc_15 = _loc_13 / this._tileHeight;
                if ((this._tileObjects[this._data[_loc_15 * this.widthInTiles + _loc_14]] as FlxTile).allowCollisions)
                {
                    _loc_14 = _loc_14 * this._tileWidth;
                    _loc_15 = _loc_15 * this._tileHeight;
                    _loc_17 = 0;
                    _loc_18 = 0;
                    _loc_20 = _loc_12 - _loc_10;
                    _loc_21 = _loc_13 - _loc_11;
                    _loc_19 = _loc_14;
                    if (_loc_6 < 0)
                    {
                        _loc_19 = _loc_19 + this._tileWidth;
                    }
                    _loc_17 = _loc_19;
                    _loc_18 = _loc_21 + _loc_11 * ((_loc_19 - _loc_20) / _loc_10);
                    if (_loc_18 > _loc_15 && _loc_18 < _loc_15 + this._tileHeight)
                    {
                        if (param3 == null)
                        {
                            param3 = new FlxPoint();
                        }
                        param3.x = _loc_17;
                        param3.y = _loc_18;
                        return false;
                    }
                    _loc_19 = _loc_15;
                    if (_loc_7 < 0)
                    {
                        _loc_19 = _loc_19 + this._tileHeight;
                    }
                    _loc_17 = _loc_20 + _loc_10 * ((_loc_19 - _loc_21) / _loc_11);
                    _loc_18 = _loc_19;
                    if (_loc_17 > _loc_14 && _loc_17 < _loc_14 + this._tileWidth)
                    {
                        if (param3 == null)
                        {
                            param3 = new FlxPoint();
                        }
                        param3.x = _loc_17;
                        param3.y = _loc_18;
                        return false;
                    }
                    return true;
                }
                _loc_16 = _loc_16 + 1;
            }
            return true;
        }// end function

        protected function autoTile(param1:uint) : void
        {
            if (this._data[param1] == 0)
            {
                return;
            }
            this._data[param1] = 0;
            if (param1 - this.widthInTiles < 0 || this._data[param1 - this.widthInTiles] > 0)
            {
                (this._data[param1] + 1);
            }
            if (param1 % this.widthInTiles >= (this.widthInTiles - 1) || this._data[(param1 + 1)] > 0)
            {
                this._data[param1] = this._data[param1] + 2;
            }
            if (param1 + this.widthInTiles >= this.totalTiles || this._data[param1 + this.widthInTiles] > 0)
            {
                this._data[param1] = this._data[param1] + 4;
            }
            if (param1 % this.widthInTiles <= 0 || this._data[(param1 - 1)] > 0)
            {
                this._data[param1] = this._data[param1] + 8;
            }
            if (this.auto == ALT && this._data[param1] == 15)
            {
                if (param1 % this.widthInTiles > 0 && param1 + this.widthInTiles < this.totalTiles && this._data[param1 + this.widthInTiles - 1] <= 0)
                {
                    this._data[param1] = 1;
                }
                if (param1 % this.widthInTiles > 0 && param1 - this.widthInTiles >= 0 && this._data[param1 - this.widthInTiles - 1] <= 0)
                {
                    this._data[param1] = 2;
                }
                if (param1 % this.widthInTiles < (this.widthInTiles - 1) && param1 - this.widthInTiles >= 0 && this._data[param1 - this.widthInTiles + 1] <= 0)
                {
                    this._data[param1] = 4;
                }
                if (param1 % this.widthInTiles < (this.widthInTiles - 1) && param1 + this.widthInTiles < this.totalTiles && this._data[param1 + this.widthInTiles + 1] <= 0)
                {
                    this._data[param1] = 8;
                }
            }
            (this._data[param1] + 1);
            return;
        }// end function

        protected function updateTile(param1:uint) : void
        {
            var _loc_2:* = this._tileObjects[this._data[param1]] as FlxTile;
            if (_loc_2 == null || !_loc_2.visible)
            {
                this._rects[param1] = null;
                return;
            }
            var _loc_3:* = (this._data[param1] - this._startingIndex) * this._tileWidth;
            var _loc_4:uint = 0;
            if (_loc_3 >= this._tiles.width)
            {
                _loc_4 = uint(_loc_3 / this._tiles.width) * this._tileHeight;
                _loc_3 = _loc_3 % this._tiles.width;
            }
            this._rects[param1] = new Rectangle(_loc_3, _loc_4, this._tileWidth, this._tileHeight);
            return;
        }// end function

        public static function arrayToCSV(param1:Array, param2:int, param3:Boolean = false) : String
        {
            var _loc_5:uint = 0;
            var _loc_6:String = null;
            var _loc_8:int = 0;
            var _loc_4:uint = 0;
            var _loc_7:* = param1.length / param2;
            while (_loc_4 < _loc_7)
            {
                
                _loc_5 = 0;
                while (_loc_5 < param2)
                {
                    
                    _loc_8 = param1[_loc_4 * param2 + _loc_5];
                    if (param3)
                    {
                        if (_loc_8 == 0)
                        {
                            _loc_8 = 1;
                        }
                        else if (_loc_8 == 1)
                        {
                            _loc_8 = 0;
                        }
                    }
                    if (_loc_5 == 0)
                    {
                        if (_loc_4 == 0)
                        {
                            _loc_6 = _loc_6 + _loc_8;
                        }
                        else
                        {
                            _loc_6 = _loc_6 + ("\n" + _loc_8);
                        }
                    }
                    else
                    {
                        _loc_6 = _loc_6 + (", " + _loc_8);
                    }
                    _loc_5 = _loc_5 + 1;
                }
                _loc_4 = _loc_4 + 1;
            }
            return _loc_6;
        }// end function

        public static function bitmapToCSV(param1:BitmapData, param2:Boolean = false, param3:uint = 1) : String
        {
            var _loc_5:uint = 0;
            var _loc_6:uint = 0;
            var _loc_10:BitmapData = null;
            var _loc_11:Matrix = null;
            if (param3 > 1)
            {
                _loc_10 = param1;
                param1 = new BitmapData(param1.width * param3, param1.height * param3);
                _loc_11 = new Matrix();
                _loc_11.scale(param3, param3);
                param1.draw(_loc_10, _loc_11);
            }
            var _loc_4:uint = 0;
            var _loc_7:String = "";
            var _loc_8:* = param1.width;
            var _loc_9:* = param1.height;
            while (_loc_4 < _loc_9)
            {
                
                _loc_5 = 0;
                while (_loc_5 < _loc_8)
                {
                    
                    _loc_6 = param1.getPixel(_loc_5, _loc_4);
                    if (param2 && _loc_6 > 0 || !param2 && _loc_6 == 0)
                    {
                        _loc_6 = 1;
                    }
                    else
                    {
                        _loc_6 = 0;
                    }
                    if (_loc_5 == 0)
                    {
                        if (_loc_4 == 0)
                        {
                            _loc_7 = _loc_7 + _loc_6;
                        }
                        else
                        {
                            _loc_7 = _loc_7 + ("\n" + _loc_6);
                        }
                    }
                    else
                    {
                        _loc_7 = _loc_7 + (", " + _loc_6);
                    }
                    _loc_5 = _loc_5 + 1;
                }
                _loc_4 = _loc_4 + 1;
            }
            return _loc_7;
        }// end function

        public static function imageToCSV(param1:Class, param2:Boolean = false, param3:uint = 1) : String
        {
            return bitmapToCSV(new param1.bitmapData, param2, param3);
        }// end function

    }
}
